package com.action.ui.fragment;


import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageButton;

import com.action.childbase.ChildBaseFragment;
import com.action.entity.Redpacket;
import com.action.entity.SystemNotice;
import com.action.entity.event.RedPacketChangeEvent;
import com.action.entity.event.TaskNewEvent;
import com.action.service.pressenter.IndexPressenter;
import com.action.ui.activity.OpenPacketActivity;
import com.action.ui.view.NumberScrollTextView;
import com.action.ui.view.UPMarqueeView;
import com.action.utils.Des;
import com.action.utils.LocUtils;
import com.action.utils.LocationKit;
import com.action.utils.SingleClick;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.base.app_core.model.Config;
import com.base.app_core.model.Paginated;
import com.base.app_core.model.dto.CosVo;
import com.base.app_core.model.dto.LocationDto;
import com.base.app_core.service.pressenter.XYBUPressenter;
import com.base.app_core.service.user.model.HomeRxBean;
import com.base.app_core.service.user.model.TaskReceiveVo;
import com.base.app_core.service.user.model.User;
import com.base.app_core.service.user.model.UserAccount;
import com.base.app_core.util.AppConstants;
import com.base.app_core.util.MaterialDialogHelper;
import com.base.app_core.util.Preferences;
import com.base.app_core.util.XYBAUtils;
import com.base.app_core.util.log.F;
import com.blankj.utilcode.util.StringUtils;
import com.hwangjr.rxbus.Bus;
import com.hwangjr.rxbus.RxBus;
import com.hwangjr.rxbus.annotation.Subscribe;
import com.hwangjr.rxbus.thread.EventThread;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.tencent.bugly.crashreport.CrashReport;
import com.tencent.map.geolocation.TencentLocation;
import com.tencent.map.geolocation.TencentLocationManager;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
import com.tencent.tencentmap.mapsdk.maps.MapView;
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
import com.tencent.tencentmap.mapsdk.maps.model.CircleOptions;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
import com.xinglai.yun.R;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.functions.Consumer;

/**
 * A simple {@link Fragment} subclass.
 */
public class RedMapFrament extends ChildBaseFragment<IndexPressenter> {

    public static final String OPEN_PACKAGE = "OPEN_PACKAGE";
    @Inject
    User user;

    @Inject
    UserAccount mUserAccount;

    @Inject
    CosVo cosVo;

    @Inject
    XYBUPressenter XYBUPressenter;

    boolean firstmovecenter = true;

    boolean frombtnclick = false;

    @Inject
    LocUtils locUtils;

    @BindView(R.id.mapview)
    MapView mMapView;

    TencentMap tencentMap;

    @Inject
    LocationDto locationDto;

    @BindView(R.id.btn_location)
    ImageButton mBtnLocation;
    @BindView(R.id.ib_send)
    ImageButton sendGiveRedpackeBt;
    @BindView(R.id.user_account)
    NumberScrollTextView userAccount;


    @BindView(R.id.upMarquee)
    UPMarqueeView upMarqueeView;

    private List<Redpacket> redpackets = new ArrayList<>();

    DecimalFormat percentDf = new DecimalFormat("######0.000");

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_index_frament;
    }


    final Animation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

    /**
     * 请求定位成功
     */
    @OnClick(R.id.btn_location)
    public void onLocation() {
        if (SingleClick.isSingle()) {
            if (null != user && null != user.getLat() && user.getLng() != null && user.getLng() != 0 && user.getLat() != 0) {
                double lat = user.getLat().doubleValue();
                double lon = user.getLng().doubleValue();
                CameraUpdate cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition
                        (new LatLng(lat, lon), getZoomLevel(user.getRange()),
                                0, 0f)); //偏航角 0~360° (正北方为0)
                tencentMap.moveCamera(cameraSigma);
            }
            loc();
            mPresenter.fetchNearRedPacket();
            XYBUPressenter.fetchUserAccount();
        }
    }

    @OnClick(R.id.user_redpacket_history)
    public void userRedpacketHistory() {
        if (SingleClick.isSingle()) {
            XYBAUtils.gotoURL(AppConstants.ROUTEURI.RED_PACKET_HISTROY);
        }
    }


    private void loc() {
        rotateAnimation.setDuration(800);
        rotateAnimation.setRepeatCount(4);
        mBtnLocation.startAnimation(rotateAnimation);

        if (SingleClick.isSingle()) {
            firstmovecenter = true;
            frombtnclick = true;
            locAndFetchPacket();
        }
    }

    private void locAndFetchPacket() {
        RxPermissions rxPermission = new RxPermissions(getActivity());
        if (rxPermission.isGranted(android.Manifest.permission.ACCESS_COARSE_LOCATION)) {
            doFetchPacket();
        } else {
            rxPermission.request(android.Manifest.permission.ACCESS_COARSE_LOCATION).subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    if (aBoolean) {
                        doFetchPacket();
                    } else {
                        MaterialDialogHelper.showSingleText(getActivity(), "需要权限谢谢", "取消", "授予", new MaterialDialogHelper.onItemClickLisener() {
                            @Override
                            public void onPosiClick(MaterialDialog dialog, DialogAction which) {
                                doFetchPacket();
                            }

                            @Override
                            public void onNatiClick(MaterialDialog dialog, DialogAction which) {
                                dialog.dismiss();
                            }
                        });
                    }
                }
            });
        }
    }

    private void doFetchPacket() {
        try {
            locUtils.requestLocation(getActivity());
            locUtils.setmTime((short) 0);
            locUtils.setOnLocationLisener(new LocUtils.LocationLisener() {

                @Override
                public void onLocationSuccess(TencentLocation location) {
                    locationDto.fillData(location);
                    user.setLat(location.getLatitude());
                    user.setLng(location.getLongitude());
                }

                @Override
                public void onLocationFailure(int error, String reason) {
                    showToast(reason);
                }
            });
            drawMarkToMap();
        } catch (Exception e) {
            e.printStackTrace();
            CrashReport.postCatchedException(e);
        }
    }

    @Override
    public void notifyError(String errorCode, String content) {
//        super.notifyError(errorCode, content);
        dismissProgress();
        showToast(content);
    }

    @Override
    protected void initView() {
        super.initView();
        locationDto.setRange(1000);

        tencentMap = mMapView.getMap();
        tencentMap.setOnMarkerClickListener(new TencentMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                if (marker == null) {
                    return false;
                }
                Redpacket redpacket = (Redpacket) marker.getTag();
                if (redpacket == null) {
                    return false;
                }

                if (SingleClick.isSingle()) {
                    startActivity(new Intent(getActivity(), OpenPacketActivity.class)
                            .putExtra(OPEN_PACKAGE, redpacket));
                } else {
                    showToast("您的动作太快啦");
                }
                return false;
            }
        });
        XYBUPressenter.attachView(this);
        locUtils.setXYBUPressenter(XYBUPressenter);
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                RxBus.get().register(RedMapFrament.this);
                getInitData();
            }
        }, 3000);
        setSendPacketView();
//        showProgress();
    }

    //F:/Users/woody/.gradle
    private void getInitData() {
        mPresenter.getCosKey();
        mPresenter.getSystemConfig();
        mPresenter.fetchSystemNotice();
        XYBUPressenter.fetchUserAccount();
    }

    private void setSendPacketView() {
        sendGiveRedpackeBt.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (locationDto.getLatitude() == 0 || locationDto.getLongitude() == 0) {
                    showToast("定位中,请稍等");
                    return;
                }

                if (SingleClick.isSingle()) {
                    XYBAUtils.gotoURL(AppConstants.ROUTEURI.GIVE_REDPACKET);
                }
            }
        });
    }

    @Subscribe(thread = EventThread.MAIN_THREAD)
    public void consumeHomeRxBeanEvent(HomeRxBean homeRxBean) {
        try {
            if (homeRxBean.getStatus() == HomeRxBean.SEND_REDPACKET) {
                RedPacketChangeEvent redPacketChangeEvent = (RedPacketChangeEvent) homeRxBean.getBean();
                if (redPacketChangeEvent.getStatus() == RedPacketChangeEvent.PACKET_SEND_ED) {
                    Redpacket redpacket = redPacketChangeEvent.getRedpacket();
                    Long id = user.getId();
                    if (redpacket != null && !redpackets.contains(redpacket)) {
                        redpackets.add(redpacket);
                    } else {
                        mPresenter.fetchNearRedPacket();
                    }
                    XYBUPressenter.fetchUserAccount();
                } else if (redPacketChangeEvent.getStatus() == RedPacketChangeEvent.PACKET_ROBED) {
                    F.w("收到监听,移除掉红包");
                    Redpacket redpacket = redPacketChangeEvent.getRedpacket();
                    if (redpacket != null) {
                        Redpacket o = new Redpacket();
                        o.setSn(redpacket.getSn());
                        redpackets.remove(o);
                    }
                } else if (redPacketChangeEvent.getStatus() == RedPacketChangeEvent.PACKET_REFRESH) {
                    loc();
                }
                locUtils.postLoc();
                drawMarkToMap();
            } else if (homeRxBean.getStatus() == HomeRxBean.USER_ACCOUNT) {
                updateView();
            }  else if (homeRxBean.getStatus() == HomeRxBean.LOC_EVENT) {
                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        loc();
                    }
                }, 1500);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Subscribe(thread = EventThread.MAIN_THREAD)
    public void consumeUserAccount(UserAccount switchAssetEvent) {
        updateView();
        if (XYBAUtils.isEmpty(redpackets)) {
            mPresenter.fetchNearRedPacket();
        }
    }

    @Override
    protected void loadData() {
        super.loadData();
        getRefreshRedPacket();
    }

    private void getRefreshRedPacket() {
        TencentLocation location = TencentLocationManager.getInstance(getActivity()).getLastKnownLocation();
        if (location != null) {
            locationDto.fillData(location);
            user.setLat(locationDto.getLatitude());
            user.setLng(locationDto.getLongitude());
            user.setProvinceCode(locationDto.getProvinceCode());
            user.setCityCode(locationDto.getCityCode());
            user.setAreaCode(locationDto.getAreaCode());
            locUtils.setmTime((short) 0);
            locUtils.postLoc();
        } else {
            loc();
        }
    }

    @Override
    protected void setupComponent() {
        super.setupComponent();
        getChildViewComponent().inject(this);
    }


    private void drawUserCircleRange(double range) {
        LatLng latLng = new LatLng(user.getLat(), user.getLng());
        tencentMap.addCircle(new CircleOptions().center(latLng).radius(range).
                fillColor(0x88ffffff).
                strokeColor(0xff909090).
                strokeWidth(1));
    }

    @Override
    public void onStart() {
        super.onStart();
        if (null != mMapView) {
            mMapView.onStart();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (null != mMapView)
            mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (null != mMapView)
            mMapView.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (null != mMapView)
            mMapView.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (null != mMapView) {
            mMapView.onDestroy();
        }

        if (locUtils != null) {
            locUtils.setOnLocationLisener(null);
        }
    }

    @Override
    public <T> void notifyData(T object, Class tClass, Paginated paginated) {
        super.notifyData(object, tClass, paginated);
        if (object instanceof Collection) {
            if (tClass == Redpacket.class) {
                Collection<? extends Redpacket> c = (Collection<? extends Redpacket>) object;
                ArrayList<Redpacket> temp = new ArrayList<>();
                temp.addAll(c);

                Long id = user.getId();
                if (user == null || id == null) {
                    return;
                }

                for (Redpacket r : redpackets) {
                    if (temp.contains(r)) {
                        int index = temp.indexOf(r);
                        Redpacket redpacket = temp.get(index);
                        redpacket.setLat(r.getLat());
                        redpacket.setLng(r.getLng());
                        redpacket.setGlobalRandomed(r.isGlobalRandomed());
                        temp.set(index, redpacket);
                    }
                }

                redpackets.clear();
                redpackets.addAll(temp);
                Collections.sort(redpackets, new Comparator<Redpacket>() {
                    @Override
                    public int compare(Redpacket o1, Redpacket o2) {
                        return o1.getType() - o2.getType();
                    }
                });
                drawMarkToMap();
            } else if (tClass == SystemNotice.class) {
                final List<SystemNotice> systemNotices = (List<SystemNotice>) object;
            } else if (tClass == Config.class) {
                List<Config> configs = (List<Config>) object;
                for (Config c : configs) {
                    //支付方式
                    if ("payTypeLimit".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        Preferences.putString(AppConstants.SP.PAY_TYPE, c.getCvalue());
                    }

                    if ("withDrawTypeLimit".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        Preferences.putString(AppConstants.SP.WITH_DRAW_TYPE_LIMIT, c.getCvalue());
                    }

                    if ("isDebug".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        F.w("cvalue===========>" + c.getCvalue());
                        if ("false".equals(c.getCvalue())) {
                            Preferences.putBoolean(AppConstants.SP.IS_DEBUG, false);
                            sendGiveRedpackeBt.setImageResource(R.mipmap.ic_btm_sndredpacket);
                        } else {
                            Preferences.putBoolean(AppConstants.SP.IS_DEBUG, true);
                            sendGiveRedpackeBt.setImageResource(R.mipmap.xidi_fajinmi_ceshi);
                        }
                    }

                    if ("appName".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        AppConstants.APPNAME = c.getCvalue();
                    }

                    if ("appIcon".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        AppConstants.APPICON = c.getCvalue();
                    }

                    if ("shareScalePercent".equals(c.getCkey()) && !StringUtils.isEmpty(c.getCvalue())) {
                        Preferences.putString(AppConstants.SP.SHARE_SCALE_PERCENT, c.getCvalue());
                    }
                }
            }
        } else if (object instanceof CosVo) {
            new AsyncTask<CosVo, Void, Void>() {
                @Override
                protected Void doInBackground(CosVo... voids) {
                    if (voids == null || voids[0] == null) {
                        return null;
                    }
                    CosVo cv = voids[0];
                    try {
                        cosVo.setBucketName(Des.decrypt(cv.getBucketName(), AppConstants.Const.K));
                        cosVo.setRegionName(Des.decrypt(cv.getRegionName(), AppConstants.Const.K));
                        cosVo.setSecretId(Des.decrypt(cv.getSecretId(), AppConstants.Const.K));
                        cosVo.setSecretKey(Des.decrypt(cv.getSecretKey(), AppConstants.Const.K));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            }.execute((CosVo) object);
        } else if (object instanceof User) {
            User user = (User) object;
            new AsyncTask<User, Void, Void>() {
                @Override
                protected Void doInBackground(User... voids) {
                    if (voids == null || voids[0] == null) {
                        return null;
                    }
                    User u = voids[0];
                    Preferences.putLong(AppConstants.SP.RANGE, u.getRange());
                    String mobile = u.getMobile();
                    if (!StringUtils.isEmpty(mobile)) {
                        Preferences.putString(AppConstants.SP.MOBILE, mobile);
                    }

                    Preferences.putBoolean(AppConstants.SP.PWD_ENABLE, u.getPwdRedPacketEnable());
                    Preferences.putString(AppConstants.SP.SNCODE, u.getAliSnCode());
                    Long id = u.getId();
                    if (id != null) {
                        Preferences.putLong(AppConstants.SP.ID, id);
                    }
                    return null;
                }
            }.execute(user);
            drawMarkToMap();
            mPresenter.fetchNearRedPacket();
            dismissProgress();
        } else if (object instanceof TaskReceiveVo) {
            TaskReceiveVo taskReceiveVo = (TaskReceiveVo) object;
            RxBus.get().post(new HomeRxBean(HomeRxBean.TASK_EVENT, new TaskNewEvent(taskReceiveVo.isTaskUnRevice())));
        }
    }


    /**
     * 初始化需要循环的View
     * 为了灵活的使用滚动的View，所以把滚动的内容让用户自定义
     * 假如滚动的是三条或者一条，或者是其他，只需要把对应的布局，和这个方法稍微改改就可以了，
     *
     * @param hotTextOne
     */
    private List<View> setView(List<SystemNotice> hotTextOne) {
        List<View> views = new ArrayList<>();


        return views;
    }

    private void updateView() {
        if (userAccount == null) {
            return;
        }

        if (StringUtils.isEmpty(mUserAccount.getAccount()))
            mUserAccount.setAccount("0");
        userAccount.setPrefixString("¥");
        userAccount.setNumberString(mUserAccount.getAccount());
        double hper = 0;
        if (!StringUtils.isEmpty(mUserAccount.getHistoryIncrease())) {
            try {
                hper = Double.parseDouble(mUserAccount.getHistoryIncrease());
                hper *= 100;
            } catch (Exception e) {

            }
        }

        double tper = 0;
        if (!StringUtils.isEmpty(mUserAccount.getTodayIncrease())) {
            try {
                tper = Double.parseDouble(mUserAccount.getTodayIncrease());
                tper *= 100;
            } catch (Exception e) {

            }
        }
    }

    private void drawMarkToMap() {
        if (tencentMap == null) {
            return;
        }

        if (user.getLat() == null || user.getLng() == null) {
            F.j("用户当前经纬度为0");
            locUtils.requestLocation(getActivity());
            return;
        }
        double lat = user.getLat().doubleValue();
        double lon = user.getLng().doubleValue();

        tencentMap.clear();
        Marker locMarker = tencentMap.addMarker(new MarkerOptions().position(new LatLng(lat, lon)));
        locMarker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_current_pos));

        Long userRange = user.getRange();
        drawUserCircleRange(userRange);
        if (firstmovecenter) {
            CameraUpdate cameraSigma = null;
            long zoomLevel = getZoomLevel(userRange);
            if (!frombtnclick) {
                cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(lat, lon), zoomLevel, 0, 0f)); //偏航角 0~360° (正北方为0)
            } else {
                cameraSigma = CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(lat, lon), zoomLevel, 0, 0f)); //偏航角 0~360° (正北方为0)
            }
            tencentMap.moveCamera(cameraSigma);
            firstmovecenter = false;
        }

        for (Redpacket redpacket : redpackets) {
            Marker marker;
            if (!redpacket.isGlobalRandomed()) {
                Long range = userRange == 0 ? 1000 : userRange * 65 / 100;
                System.out.println("user.getLat " + user.getLat().doubleValue() + "user.getLng " + user.getLng() + "range " + range);
                double[] around = LocationKit.getAround(user.getLat(), user.getLng(), range.intValue());
                marker = tencentMap.addMarker(new MarkerOptions().tag(redpacket).position(LocationKit.randomLonLat(redpacket, around[1], around[3], around[0], around[2])));
                redpacket.setGlobalRandomed(true);
            } else {
                marker = tencentMap.addMarker(new MarkerOptions().tag(redpacket).position(new LatLng(redpacket.getLat(), redpacket.getLng())));
            }
            setRedPacketType(redpacket, marker);
        }
    }

    private long getZoomLevel(Long userRange) {
//        return Math.max(14 - (userRange / 1000 / 2), 8);
        return scale2Zoom(Integer.parseInt(String.valueOf(userRange / 4)));
    }

    /**
     * “scale-zoom”映射关系：https://www.cnblogs.com/yesyes/p/6785705.html
     *
     * @param scale 比例尺
     * @return zoom值
     */
    private int scale2Zoom(int scale) {
        if (scale <= 10) return 19;
        else if (scale <= 25) return 18;
        else if (scale <= 50) return 17;
        else if (scale <= 100) return 16;
        else if (scale <= 200) return 15;
        else if (scale <= 500) return 14;
        else if (scale <= 1000) return 13;
        else if (scale <= 2000) return 12;
        else if (scale <= 5000) return 11;
        else if (scale <= 10000) return 10;
        else if (scale <= 20000) return 9;
        else if (scale <= 30000) return 8;
        else if (scale <= 50000) return 7;
        else if (scale <= 100000) return 6;
        else if (scale <= 200000) return 5;
        else if (scale <= 500000) return 4;
        else if (scale <= 1000000) return 3;
        else if (scale > 1000000) return 2;
        return 20;
    }

    private void setRedPacketType(Redpacket redpacket, Marker marker) {
        if (redpacket.getType() == null)
            redpacket.setType(0);
        switch (redpacket.getType()) {
            case 0:
                marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_hongbao_ad));
                break;
            case 1:
                marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_hongbao_mima));
                break;
            case 2:
                marker.setIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_hongbao_pingtai));
                break;
        }
        marker.setClickable(true);
    }

    @Override
    protected boolean isNeedShowLoading() {
        return false;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Bus bus = RxBus.get();
        if (bus.hasRegistered(this)) {
            bus.unregister(this);
        }
    }
}
